#include "page.h"

typedef vector<vector <unsigned int> > VECVECU;
typedef vector<unsigned int> VECU;

Page::Page(ifstream& filestr) {
	m_nbline=0;  
	if (!filestr)
	{
                cerr<<"NON RIESCO AD APRIRE IL FILE ???"<<'\n'<<'\n'<<'\n';
		m_ErrFile=1;
	}
	else
	{
		m_ErrFile=0;
		cout<<"FILE APERTO CON SUCCESSO..."<<'\n'<<'\n'<<'\n'; 
		string str;
		while (filestr.eof() == 0)
		{
			getline(filestr,str,'\n');
			m_nbline++;
 			m_page.push_back(str);
            cout<<str;
            cout<<'\n';

		}
		cout<<"...RAGGIUNTA FINE DEL FILE !!!"<<'\n'<<'\n'<<'\n'; 
		filestr.close();
	}
}

Page::Page() : m_nbline(0), m_ErrFile(0) { }

Page::Page(const char* str) {
	m_ErrFile=0;
	string stmp=str;
	m_page.push_back(str);
	m_nbline=1;
}

Page::Page(const string& str) {
	m_ErrFile=0;
	m_page.push_back(str);
	m_nbline=1;
}


Page& Page::operator=(v_string& v)
{	
	vector <string>::iterator r;
	m_ErrFile=0;
	m_nbline=0;
	for (r=v.begin(); r!=v.end(); r++)
	{
		this->add_line(*r);
	}
	return *this;
}


string Page::get_line(const unsigned int& nbl) const {
	string str;
	if (nbl>0 && nbl<=m_nbline)
			str=m_page[nbl-1];
	else
			str="";
	return str;
}

unsigned int Page::get_nbline() const {
	return m_nbline;
}

int Page::get_width() const {
	unsigned int m_width=0;
	unsigned int m_width_tmp=0;
	int r;
	for (r=0; r<m_nbline; r++) {
		m_width_tmp=m_page[r].length();
		if (m_width_tmp>m_width) {
			m_width=m_width_tmp;
		}
	}
	return m_width;
}

void Page::add_line(const char* str) {
	string stmp=str;
	m_nbline++;
	m_page.push_back(str);
}

void Page::add_line(const string& str) {
	m_nbline++;
	m_page.push_back(str);
}

void  Page::add_line_begin(const char* str)
{
    m_nbline++;
    m_page.insert(m_page.begin(),str);
}

void Page::add_page(const Page& p)
{
	int r;
	for (r=0; r<p.get_nbline(); r++) 
	{
		this->add_line(p.get_line(r+1));
	}	
}

void Page::del_line(const int& nbl) {
	if (nbl>0 && nbl<=m_nbline) {
		m_page.erase(m_page.begin()+nbl-1);
		m_nbline--;
	}
}

void Page::Print(ostream& os, const char* str_mark_l, const char* str_mark_r) const
{
	int r;
	for (r=0; r<m_nbline; r++) 
	{
		os<<str_mark_l<<m_page[r]<<str_mark_r<<'\n';
	}
}

/*
Page& Page::operator<<(ostream& os)
{	
	int r;
	for (r=0; r<this->m_nbline; r++) 
	{
		os<<'|'<<this->m_page[r]<<'|'<<'\n';
	}
	return *this;
}

ostream& Page::operator<<(Page& p)
{	
	streambuf* psb = 0; 
	ostream os(psb);
	int r;
	for (r=0; r<p.m_nbline; r++) 
	{
		os<<'|'<<p.m_page[r]<<'|'<<'\n';
	}
	return os;
}


ostream& operator<<(ostream& os, Page & p)
{
	int r;
	for (r=0; r<p.m_nbline; r++) 
	{
		os<<'|'<<p.m_page[r]<<'|'<<'\n';
	}
	return os;
};
*/


/* istream& operator>>(istream& is, Page& pg) {
	string str;
	is>>str;
	pg.add_line(str);
	return is;
}
*/

unsigned int Page::find(const string str, unsigned int posI, unsigned int posF) {
	unsigned int pos = 0;
	m_str2find=str;
	m_nb_row_find.clear();
	m_pos_row_find.clear();
	unsigned int total=0;
	vector<unsigned int> curr_pos_row;
	int curr_pos;
	int r;
	int cp;
	if (posF==0) posF=m_nbline;
	posI=posI-1;
	for (r=posI; r<posF; r++) {
		curr_pos=m_page[r].find(str,pos);
		cp=curr_pos;
			while (curr_pos!=-1) {
				total++;
				curr_pos_row.push_back(curr_pos);
				curr_pos=m_page[r].find(str,curr_pos+str.length());
			}
			if (cp!=-1) {
				m_nb_row_find.push_back(r+1);
				m_pos_row_find.push_back(curr_pos_row);
				curr_pos_row.clear();
			}
	}
	m_finded=total;
	return total;
}

unsigned int Page::Replace(const char* old_s, const char* new_s)
{
	string old_str = old_s;
	string new_str = new_s;
	unsigned int pos = 0;
	unsigned int total = 0;
	int curr_pos;
	int r;
	int cp;
	for (r=0; r<m_nbline; r++) 
	{
		curr_pos=m_page[r].find(old_str,pos);
		cp=curr_pos;
			while (curr_pos!=-1) 
			{
				total++;
				// curr_pos_row.push_back(curr_pos);
				// m_page[r].replace();
				m_page[r] = m_page[r].replace(curr_pos,old_str.length(),new_str);
				curr_pos=m_page[r].find(old_str,curr_pos+old_str.length());
			}
	}
	return(total);
}

string Page::get_strfinded() const { return m_str2find; } 

vector<unsigned int> Page::get_nb_row_find() const { return  m_nb_row_find; }         

vector< vector<unsigned int> > Page::get_pos_row_find() const { return  m_pos_row_find;} 

unsigned int Page::get_pos_row_find(const unsigned int &r, const unsigned int &c) const { return  m_pos_row_find[r][c];} 

void Page::show_finded(ostream& os) {
	VECVECU::iterator r;
	VECU::iterator c;
	VECU w;
	os<<"Stringa cercata: "<<m_str2find<<'\n';
	os<<"Posizioni in cui si trova la stringa: "<<'\n';
	os<<"---------------------------------------- "<<'\n';
	for (r=m_pos_row_find.begin(); r!=m_pos_row_find.end(); r++) {
		w=*r;
		for (c=w.begin(); c!=w.end(); c++) {

			os.precision(2);
			os.setf(ios::fixed);
			os.setf(ios::right);
			os.width(10);

			os<<*c;
		}
		os<<'\n';
	}
	os<<"---------------------------------------- "<<'\n'<<'\n';
	os<<"Righe in cui si trova la stringa: "<<'\n';
	os<<"--------------------------------- "<<'\n';
	os<<"[";
	for (c=m_nb_row_find.begin(); c!=m_nb_row_find.end(); c++) {
			os.precision(2);
			os.setf(ios::fixed);
			os.setf(ios::right);
			os<<*c;
			if (c!=m_nb_row_find.end()-1) os<<",";
	}
	os<<"]"<<'\n'<<'\n';
	os<<"Numero totale di occorrenze: "<<m_finded<<'\n'<<'\n';
}

unsigned int Page::ErrFile() {
	return m_ErrFile;
}

bool Page::IsEmpty(void) const
{
	if (m_nbline == 0) return(true);
	return(false);
}

void Page::Clear(void)
{
m_nbline = 0;
m_ErrFile = 0;
m_page.clear();
}

// Page::Page(const v_string & v) { }
